home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / emacs.lha / emacs-19.16 / oldXMenu / Create.c < prev    next >
C/C++ Source or Header  |  1993-06-09  |  21KB  |  745 lines

  1. /* $Header: /u/src/emacs/19.0/oldXMenu/RCS/Create.c,v 1.4 1993/03/09 18:18:01 jimb Exp $ */
  2. /* Copyright    Massachusetts Institute of Technology    1985    */
  3.  
  4. #include "copyright.h"
  5.  
  6. /*
  7.  * XMenu:    MIT Project Athena, X Window system menu package
  8.  *
  9.  *     XMenuCreate -    Creates an X window system menu object.
  10.  *
  11.  *    Author:        Tony Della Fera, DEC
  12.  *            January 23, 1986
  13.  *
  14.  */
  15.  
  16. #include "XMenuInt.h"
  17.  
  18.  
  19. #ifdef EMACS_BITMAP_FILES
  20. #include "../src/bitmaps/dimple1.xbm"
  21. #include "../src/bitmaps/dimple3.xbm"
  22. #include "../src/bitmaps/gray1.xbm"
  23. #include "../src/bitmaps/gray3.xbm"
  24. #include "../src/bitmaps/crosswv.xbm"
  25.  
  26. #include "../src/bitmaps/leftptr.xbm"
  27. #include "../src/bitmaps/leftpmsk.xbm"
  28. #include "../src/bitmaps/rtptr.xbm"
  29. #include "../src/bitmaps/rtpmsk.xbm"
  30. #include "../src/bitmaps/cntrptr.xbm"
  31. #include "../src/bitmaps/cntrpmsk.xbm"
  32. #include "../src/bitmaps/stipple.xbm"
  33.  
  34. #else
  35. #ifndef VMS
  36.  
  37. #include <X11/bitmaps/dimple1>
  38. #include <X11/bitmaps/dimple3>
  39. #include <X11/bitmaps/gray1>
  40. #include <X11/bitmaps/gray3>
  41. #include <X11/bitmaps/cross_weave>
  42.  
  43. #include <X11/bitmaps/left_ptr>
  44. #include <X11/bitmaps/left_ptrmsk>
  45. #include <X11/bitmaps/right_ptr>
  46. #include <X11/bitmaps/right_ptrmsk>
  47. #include <X11/bitmaps/cntr_ptr>
  48. #include <X11/bitmaps/cntr_ptrmsk>
  49. #include <X11/bitmaps/stipple>
  50.  
  51. #else
  52.  
  53. #include "[-.src.bitmaps]dimple1.xbm"
  54. #include "[-.src.bitmaps]dimple3.xbm"
  55. #include "[-.src.bitmaps]gray1.xbm"
  56. #include "[-.src.bitmaps]gray3.xbm"
  57. #include "[-.src.bitmaps]crosswv.xbm"
  58.  
  59. #include "[-.src.bitmaps]leftptr.xbm"
  60. #include "[-.src.bitmaps]leftpmsk.xbm"
  61. #include "[-.src.bitmaps]rtptr.xbm"
  62. #include "[-.src.bitmaps]rtpmsk.xbm"
  63. #include "[-.src.bitmaps]cntrptr.xbm"
  64. #include "[-.src.bitmaps]cntrpmsk.xbm"
  65. #include "[-.src.bitmaps]stipple.xbm"
  66.  
  67. #endif /* VMS */
  68. #endif /* not EMACS_BITMAP_FILES */
  69.  
  70. #define DEF_FREEZE        0
  71. #define DEF_REVERSE        0
  72. #define DEF_MENU_STYLE        LEFT
  73. #define DEF_MENU_MODE        BOX
  74. #define DEF_INACT_PNUM        3
  75. #define MAX_INACT_PNUM        4
  76.  
  77. #define DEF_P_STYLE        CENTER
  78.  
  79. #define DEF_P_EVENTS        (EnterWindowMask | ExposureMask)
  80. #define DEF_P_FNT_NAME        "fixed"
  81. #define DEF_P_SPREAD        0.5
  82. #define DEF_P_BDR_WIDTH        2
  83.  
  84. #define DEF_S_STYLE        LEFT
  85. #define DEF_S_EVENTS        (EnterWindowMask | LeaveWindowMask)
  86. #define DEF_S_FNT_NAME        "fixed"
  87. #define DEF_S_SPREAD        0.10
  88. #define DEF_S_BDR_WIDTH        1
  89.  
  90. #define XASSOC_TABLE_SIZE    64
  91.  
  92. #define TILE_BUF_SIZE        5
  93.  
  94. int atoi();
  95. double atof();
  96. char *x_get_resource_string ();
  97.  
  98. XMenu *
  99. XMenuCreate(display, parent, def_env)
  100.     Display *display;           /* ID of previously opened display */
  101.     Window parent;        /* Window ID of the menu's parent window. */
  102.     register char *def_env;    /* X Defaults program environment name. */
  103. {
  104.   register int i;        /* Loop counter. */
  105.   register int j;        /* Loop counter. */
  106.   register char *def_val;    /* X Default value temp variable. */
  107.  
  108.   register XMenu *menu;        /* Pointer to the new menu. */
  109.   XMStyle menu_style;        /* Menu display style. */
  110.   XMMode menu_mode;        /* Menu display mode. */
  111.   XMPane *pane;            /* Pane list header. */
  112.   XAssocTable *assoc_tab;    /* XAssocTable pointer. */
  113.  
  114.   int freeze;            /* Freeze server mode. */
  115.   int reverse;            /* Reverse video mode. */
  116.  
  117.   XMStyle p_style;        /* Pane display style. */
  118.   char *p_fnt_name;        /* Flag font name. */
  119.   XFontStruct *p_fnt_info;    /* Flag font structure */
  120.   int p_fnt_pad;        /* Flag font padding in pixels. */
  121.   double p_spread;        /* Pane spread in flag height fractions. */
  122.   int p_fnt_height;        /* Pane character height. */
  123.   int p_bdr_width;        /* Pane border width. */
  124.   int flag_height;        /* Flag window height. */
  125.   int p_height;            /* Pane window height. */
  126.   int p_x_off;            /* Pane X offset. */
  127.   int p_y_off;            /* Pane Y offset. */
  128.   GC pane_GC;            /* Pane graphics context. */
  129.  
  130.   XMStyle s_style;        /* Selection display style. */
  131.   char *s_fnt_name;        /* Selection font name. */
  132.   XFontStruct *s_fnt_info;    /* Selection font structure. */
  133.   int s_fnt_pad;        /* Selection font padding in pixels. */
  134.   int s_fnt_height;        /* Selection font character height */
  135.   double s_spread;        /* Select spread in line height fractions. */
  136.   int s_bdr_width;        /* Highlight border width. */
  137.   int s_height;            /* Selection window height. */
  138.   int s_x_off;            /* Selection window X offset. */
  139.   int s_y_off;            /* Selection window Y offset. */
  140.   GC normal_select_GC;        /* GC used for normal video selection. */
  141.   GC inverse_select_GC;        /* GC used for inverse video selection. */
  142.   GC inact_GC;            /* GC for inactive pane header and */
  143.   /* selections. */
  144.   GC inact_GC_noexpose;
  145.  
  146.   XColor color_def;        /* Temp color definition holder. */
  147.   XColor screen_def;        /* Temp screen color definition holder */
  148.   XColor p_bdr_color;        /* Color of border. */
  149.   XColor s_bdr_color;        /* Color of highlight. */
  150.   XColor p_frg_color;        /* Color of pane foreground color. */
  151.   XColor s_frg_color;        /* Color of selection foreground. */
  152.   XColor bkgnd_color;        /* Color of background.. */
  153.   XColor mouse_color;        /* Color of mouse cursor. */
  154.   Cursor mouse_cursor;        /* Mouse cursor. */
  155.   Pixmap inact_bitmap;        /* Menu inactive pixmap. */
  156.  
  157.   int inact_pnum;        /* Inactive background pattern number. */
  158.  
  159.   Pixel p_bdr_pixel;            /* Pane border pixel. */
  160.   Pixel s_bdr_pixel;            /* Selection border pixel. */
  161.   Pixel p_frg_pixel;            /* Pane foreground pixel. */
  162.   Pixel s_frg_pixel;            /* Selection foreground pixel. */
  163.   Pixel bkgnd_pixel;            /* Menu background pixel. */
  164.  
  165.   int *width, *height;
  166.   Pixmap *bitmap;
  167.   int *x_hot, *y_hot;
  168.   int status;            /* Return code from XReadBitmapFile. */
  169.  
  170.   Pixmap cursor;        /* Cursor pixmap holder. */
  171.   Pixmap cursor_mask;        /* Cursor mask pixmap holder. */
  172.   Pixmap stipple_pixmap;    /* Stippple mask for half-tone text. */
  173.   unsigned long valuemask;
  174.   XGCValues *values;
  175.     
  176.   Window root = RootWindow (display, DefaultScreen (display));
  177.  
  178.   /*
  179.    * Calloc the XMenu structure and the initial pane.
  180.    */
  181.   menu = (XMenu *)calloc(1, sizeof(XMenu));
  182.   if (menu == NULL) {
  183.     _XMErrorCode = XME_CALLOC;
  184.     return(NULL);
  185.   }
  186.   pane = (XMPane *)calloc(1, sizeof(XMPane));
  187.   if (pane == NULL) {
  188.     _XMErrorCode = XME_CALLOC;
  189.     return(NULL);
  190.   }
  191.     
  192.   /* 
  193.    * Create the XAssocTable
  194.    */
  195.   assoc_tab = (XAssocTable *)XCreateAssocTable(XASSOC_TABLE_SIZE);
  196.   if(assoc_tab == NULL) {
  197.     _XMErrorCode= XME_CREATE_ASSOC;
  198.     return(NULL);
  199.   }
  200.  
  201.   /*
  202.    * Set up the default environment name.
  203.    */
  204.   if (def_env == NULL || *def_env == '\0') def_env = "XMenu";
  205.  
  206.   /*
  207.    * Set up internal fail-safe defaults.
  208.    */
  209.   freeze = DEF_FREEZE;
  210.   reverse = DEF_REVERSE;
  211.   menu_style = DEF_MENU_STYLE;
  212.   menu_mode = DEF_MENU_MODE;
  213.   inact_pnum = DEF_INACT_PNUM;
  214.  
  215.   p_style = DEF_P_STYLE;
  216.   p_spread = DEF_P_SPREAD;
  217.   p_fnt_name = DEF_P_FNT_NAME;
  218.   p_bdr_width = DEF_P_BDR_WIDTH;
  219.  
  220.   s_style = DEF_S_STYLE;
  221.   s_spread = DEF_S_SPREAD;
  222.   s_fnt_name = DEF_S_FNT_NAME;
  223.   s_bdr_width = DEF_S_BDR_WIDTH;
  224.  
  225.   /*
  226.    * Get default values from X.
  227.    */
  228.   def_val = x_get_resource_string ("menuFreeze", "MenuFreeze");
  229.   if (def_val != NULL) {
  230.     if (strcmp(def_val, "on") == 0) freeze = 1;
  231.     else if (strcmp(def_val, "off") == 0) freeze = 0;
  232.   }
  233.  
  234.   def_val = x_get_resource_string ("menuReverseVideo", "MenuReverseVideo");
  235.   if (def_val != NULL) {
  236.     if (strcmp(def_val, "on") == 0) reverse = 1;
  237.     else if (strcmp(def_val, "off") == 0) reverse = 0;
  238.   }
  239.  
  240.   def_val = x_get_resource_string ("menuStyle", "MenuStyle");
  241.   if (def_val != NULL) {
  242.     if (strcmp(def_val, "right_hand") == 0) menu_style = RIGHT;
  243.     else if (strcmp(def_val, "left_hand") == 0) menu_style = LEFT;
  244.     else if (strcmp(def_val, "center") == 0) menu_style = CENTER;
  245.   }
  246.  
  247.   def_val = x_get_resource_string ("menuMode", "MenuMode");
  248.   if (def_val != NULL) {
  249.     if (strcmp(def_val, "box") == 0) menu_mode = BOX;
  250.     else if (strcmp(def_val, "invert") == 0) menu_mode = INVERT;
  251.   }
  252.     
  253.   def_val = x_get_resource_string ("menuMouse", "MenuMouse");
  254.   if (
  255.       def_val != NULL &&
  256.       DisplayCells(display, DefaultScreen(display)) > 2 &&
  257.       XAllocNamedColor(display, 
  258.                DefaultColormap(display, DefaultScreen(display)), 
  259.                def_val, 
  260.                &mouse_color, &color_def)
  261.       );
  262.   else if (reverse &&
  263.        XAllocNamedColor(display,
  264.                 DefaultColormap(display, DefaultScreen(display)),
  265.                 "white",
  266.                 &mouse_color, &color_def)
  267.        );
  268.     
  269.   else if (XAllocNamedColor(display,
  270.                 DefaultColormap(display, DefaultScreen(display)),
  271.                 "black", 
  272.                 &mouse_color, &color_def)
  273.        );
  274.     
  275.   else ;
  276.  
  277.   def_val = x_get_resource_string ("menuBackground", "MenuBackground");
  278.   if (
  279.       def_val != NULL &&
  280.       DisplayCells(display, DefaultScreen(display)) > 2 &&
  281.       XAllocNamedColor(display,
  282.                DefaultColormap(display, DefaultScreen(display)),
  283.                def_val,
  284.                &bkgnd_color, &color_def)
  285.       );
  286.   else if (reverse &&
  287.        XAllocNamedColor(display,
  288.                 DefaultColormap(display, DefaultScreen(display)),
  289.                 "black",
  290.                 &bkgnd_color, &color_def)
  291.        );
  292.   else if (XAllocNamedColor(display,
  293.                 DefaultColormap(display, DefaultScreen(display)),
  294.                 "white",
  295.                 &bkgnd_color, &color_def)
  296.        );
  297.   else;
  298.  
  299.   def_val = x_get_resource_string ("menuInactivePattern", "MenuInactivePattern");
  300.   if (def_val != NULL) {
  301.     if (strcmp(def_val, "dimple1") == 0) inact_pnum = 0;
  302.     else if (strcmp(def_val, "dimple3") == 0) inact_pnum = 1;
  303.     else if (strcmp(def_val, "gray1") == 0) inact_pnum = 2;
  304.     else if (strcmp(def_val, "gray3") == 0) inact_pnum = 3;
  305.     else if (strcmp(def_val, "cross_weave") == 0) inact_pnum = 4;
  306.   }
  307.  
  308.   def_val = x_get_resource_string ("paneStyle", "PaneStyle");
  309.   if (def_val != NULL) {
  310.     if (strcmp(def_val, "flush_left") == 0) p_style = LEFT;
  311.     else if (strcmp(def_val, "flush_right") == 0) p_style = RIGHT;
  312.     else if (strcmp(def_val, "center") == 0) p_style = CENTER;
  313.   }
  314.  
  315.   def_val = x_get_resource_string ("paneFont", "PaneFont");
  316.   if (def_val != NULL) p_fnt_name = def_val;
  317.  
  318.   def_val = x_get_resource_string ("paneForeground", "PaneForeground");
  319.   if (
  320.       def_val != NULL &&
  321.       DisplayCells(display, DefaultScreen(display)) > 2 
  322.       )
  323.     XAllocNamedColor(display, DefaultColormap(display,
  324.                           DefaultScreen(display)),
  325.              def_val,
  326.              &p_frg_color, &color_def);
  327.       
  328.   else if (reverse) XAllocNamedColor(display,
  329.                      DefaultColormap(display, 
  330.                              DefaultScreen(display)),
  331.                      "white",
  332.                      &p_frg_color, &color_def);
  333.   else XAllocNamedColor(display,
  334.             DefaultColormap(display, DefaultScreen(display)),
  335.             "black",
  336.             &p_frg_color, &color_def);
  337.  
  338.   def_val = x_get_resource_string ("paneBorder", "PaneBorder");
  339.   if (
  340.       def_val != NULL &&
  341.       DisplayCells(display, DefaultScreen(display)) > 2 &&
  342.       XAllocNamedColor(display,
  343.                DefaultColormap(display, DefaultScreen(display)),
  344.                def_val,
  345.                &p_bdr_color, &color_def)
  346.       );
  347.   else if (reverse &&
  348.        XAllocNamedColor(display, 
  349.                 DefaultColormap(display, DefaultScreen(display)),
  350.                 "white",
  351.                 &p_bdr_color, &color_def)
  352.        );
  353.   else XAllocNamedColor(display, 
  354.             DefaultColormap(display, DefaultScreen(display)),
  355.             "black",
  356.             &p_bdr_color, &color_def);
  357.     
  358.   def_val = x_get_resource_string ("paneBorderWidth", "PaneBorderWidth");
  359.   if (def_val != NULL) p_bdr_width = atoi(def_val);
  360.     
  361.   def_val = x_get_resource_string ("paneSpread", "PaneSpread");
  362.   if (def_val != NULL) p_spread = atof(def_val);
  363.  
  364.   def_val = x_get_resource_string ("selectionStyle", "SelectionStyle");
  365.   if (def_val != NULL) {
  366.     if (strcmp(def_val, "flush_left") == 0) s_style = LEFT;
  367.     else if (strcmp(def_val, "flush_right") == 0) s_style = RIGHT;
  368.     else if (strcmp(def_val, "center") == 0) s_style = CENTER;
  369.   }
  370.  
  371.   def_val = x_get_resource_string ("selectionFont", "SelectionFont");
  372.   if (def_val != NULL) s_fnt_name = def_val;
  373.  
  374.   def_val = x_get_resource_string ("selectionForeground", "SelectionForeground");
  375.   if (
  376.       def_val != NULL &&
  377.       DisplayCells(display, DefaultScreen(display)) > 2 &&
  378.       XAllocNamedColor(display,
  379.                DefaultColormap(display, DefaultScreen(display)),
  380.                def_val,
  381.                &s_frg_color, &color_def)
  382.       ); 
  383.   else if (reverse &&
  384.        XAllocNamedColor(display,
  385.                 DefaultColormap(display, DefaultScreen(display)),
  386.                 "white",
  387.                 &s_frg_color, &color_def)
  388.        ) ;
  389.   else if (XAllocNamedColor(display,
  390.                 DefaultColormap(display, DefaultScreen(display)),
  391.                 "black",
  392.                 &s_frg_color, &color_def)
  393.        ) ;
  394.   else ;
  395.     
  396.  
  397.   def_val = x_get_resource_string ("selectionBorder", "SelectionBorder");
  398.   if (
  399.       def_val != NULL &&
  400.       DisplayCells(display, DefaultScreen(display)) > 2 &&
  401.       XAllocNamedColor(display,
  402.                DefaultColormap(display, DefaultScreen(display)),
  403.                def_val,
  404.                &s_bdr_color, &color_def)
  405.       ) ;
  406.   else if (reverse &&
  407.        XAllocNamedColor(display, 
  408.                 DefaultColormap(display, DefaultScreen(display)),
  409.                 "white",
  410.                 &s_bdr_color, &color_def)
  411.        ) ;
  412.   else if (XAllocNamedColor(display,
  413.                 DefaultColormap(display, DefaultScreen(display)),
  414.                 "black",
  415.                 &s_bdr_color, &color_def)
  416.        ) ;
  417.   else ;
  418.  
  419.   def_val = x_get_resource_string ("selectionBorderWidth", "SelectionBorderWidth");
  420.   if (def_val != NULL) s_bdr_width = atoi(def_val);
  421.     
  422.   def_val = x_get_resource_string ("selectionSpread", "SelectionSpread");
  423.   if (def_val != NULL) s_spread = atof(def_val);
  424.  
  425.   /*
  426.    * Create and store the inactive pattern pixmap.
  427.    */
  428.   {
  429.     char *data = NULL;
  430.     int width, height;
  431.  
  432.     switch (inact_pnum) 
  433.       {
  434.       case 0:
  435.     data = dimple1_bits;
  436.     width = dimple1_width;
  437.     height = dimple1_height;
  438.     break;
  439.  
  440.       case 1:
  441.     data = dimple3_bits;
  442.     width = dimple3_width;
  443.     height = dimple3_height;
  444.     break;
  445.  
  446.       case 2:
  447.     data = gray1_bits;
  448.     width = gray1_width;
  449.     height = gray1_height;
  450.     break;
  451.  
  452.       case 3:
  453.     data = gray3_bits;
  454.     width = gray3_width;
  455.     height = gray3_height;
  456.     break;
  457.  
  458.       case 4:
  459.     data = cross_weave_bits;
  460.     width = cross_weave_width;
  461.     height = cross_weave_height;
  462.     break;
  463.       }
  464.  
  465.     if (! data)
  466.       {
  467.     _XMErrorCode = XME_STORE_BITMAP;
  468.     return(NULL);
  469.       }
  470.  
  471.     inact_bitmap =
  472.       XCreatePixmapFromBitmapData
  473.     (display, root, data, width, height,
  474.      p_frg_color.pixel, bkgnd_color.pixel,
  475.      DisplayPlanes (display, DefaultScreen (display)));
  476.   }
  477.  
  478.   /*
  479.    * Load the mouse cursor.
  480.    */
  481.       
  482.   switch (menu_style) {
  483.   case LEFT:
  484.     cursor = XCreateBitmapFromData(display,
  485.                    root,
  486.                    left_ptr_bits,
  487.                    left_ptr_width,
  488.                    left_ptr_height);
  489.     cursor_mask = XCreateBitmapFromData(display,
  490.                     root,
  491.                     left_ptrmsk_bits,
  492.                     left_ptrmsk_width,
  493.                     left_ptrmsk_height);
  494.     mouse_cursor = XCreatePixmapCursor(
  495.                        display,
  496.                        cursor, cursor_mask, 
  497.                        &mouse_color, &bkgnd_color,
  498.                        left_ptr_x_hot,
  499.                        left_ptr_y_hot
  500.                        );
  501.     XFreePixmap(display, cursor);
  502.     XFreePixmap(display, cursor_mask);        
  503.     break;
  504.   case RIGHT:
  505.     cursor = XCreateBitmapFromData(display,
  506.                    root,
  507.                    right_ptr_bits,
  508.                    right_ptr_width,
  509.                    right_ptr_height);
  510.     cursor_mask = XCreateBitmapFromData(display,
  511.                     root,
  512.                     right_ptrmsk_bits,
  513.                     right_ptrmsk_width,
  514.                     right_ptrmsk_height);
  515.     mouse_cursor = XCreatePixmapCursor(
  516.                        display,
  517.                        cursor, cursor_mask,
  518.                        &mouse_color, &bkgnd_color,
  519.                        right_ptr_x_hot,
  520.                        right_ptr_y_hot
  521.                        );
  522.     XFreePixmap(display, cursor);
  523.     XFreePixmap(display, cursor_mask);        
  524.     break;
  525.   case CENTER:
  526.     cursor = XCreateBitmapFromData(display,
  527.                    root,
  528.                    cntr_ptr_bits,
  529.                    cntr_ptr_width,
  530.                    cntr_ptr_height);
  531.     cursor_mask = XCreateBitmapFromData(display,
  532.                     root,
  533.                     cntr_ptrmsk_bits,
  534.                     cntr_ptrmsk_width,
  535.                     cntr_ptrmsk_height);
  536.     mouse_cursor = XCreatePixmapCursor(
  537.                        display,
  538.                        cursor, cursor_mask,
  539.                        &mouse_color, &bkgnd_color,
  540.                        cntr_ptr_x_hot,
  541.                        cntr_ptr_y_hot
  542.                        );
  543.     XFreePixmap(display, cursor);
  544.     XFreePixmap(display, cursor_mask);        
  545.     break;
  546.   default:
  547.     /* Error! Invalid style parameter. */
  548.     _XMErrorCode = XME_STYLE_PARAM;
  549.     return(NULL);
  550.   }
  551.   if (mouse_cursor == _X_FAILURE) {
  552.     _XMErrorCode = XME_CREATE_CURSOR;
  553.     return(NULL);
  554.   }
  555.  
  556.   /*
  557.    * Open the pane and selection fonts.
  558.    */
  559.     
  560.   p_fnt_info = XLoadQueryFont(display, p_fnt_name);
  561.   if (p_fnt_info == NULL) {
  562.     _XMErrorCode = XME_OPEN_FONT;
  563.     return(NULL);
  564.     
  565.   }
  566.  
  567.   s_fnt_info = XLoadQueryFont(display, s_fnt_name);
  568.   if (s_fnt_info == NULL) {
  569.     _XMErrorCode = XME_OPEN_FONT;
  570.     return(NULL);
  571.   }
  572.   /*
  573.    * Calculate the fixed padding value in pixels for each font.
  574.    */
  575.   p_fnt_height = p_fnt_info->max_bounds.ascent + p_fnt_info->max_bounds.descent;
  576.   s_fnt_height = s_fnt_info->max_bounds.ascent + s_fnt_info->max_bounds.descent;
  577.   p_fnt_pad = s_spread * p_fnt_height;
  578.   s_fnt_pad = s_spread * s_fnt_height;
  579.  
  580.   /*
  581.    * Calculate fixed height and offset requirements.
  582.    */
  583.   flag_height = p_fnt_height + (p_fnt_pad << 1);
  584.  
  585.   p_height = 0;
  586.   p_y_off = flag_height + p_bdr_width;
  587.   p_x_off = p_y_off * p_spread;
  588.  
  589.   s_height = s_fnt_height + (s_fnt_pad << 1) + (s_bdr_width << 1);
  590.   s_y_off = s_height;
  591.   s_x_off = p_x_off;
  592.  
  593.   /*
  594.    * Set up the pane list header.
  595.    */
  596.   pane->next = pane;
  597.   pane->prev = pane;
  598.   pane->type = PL_HEADER;
  599.   pane->serial = -1;
  600.  
  601.   /*
  602.    * Initialize the internal pane and selection creation queues.
  603.    */
  604.   _XMWinQueInit();
  605.     
  606.   /*
  607.    * Create pane, active, and inactive GC's.
  608.    */
  609.   values = (XGCValues *)malloc(sizeof(XGCValues));
  610.   valuemask = (GCForeground | GCBackground | GCFont | GCLineWidth);
  611.  
  612.   /*
  613.    * First, pane.
  614.    */
  615.  
  616.   values->foreground = p_frg_color.pixel;
  617.   values->background = bkgnd_color.pixel;
  618.   values->font = p_fnt_info->fid;
  619.   values->line_width = p_bdr_width;
  620.     
  621.   pane_GC = XCreateGC(
  622.               display, 
  623.               root,
  624.               valuemask,
  625.               values);
  626.   /*
  627.    * Then normal video selection.
  628.    */
  629.  
  630.   values->foreground = s_frg_color.pixel;
  631.   values->background = bkgnd_color.pixel;
  632.   values->font = s_fnt_info->fid;
  633.   values->line_width = s_bdr_width;
  634.   normal_select_GC = XCreateGC(display, 
  635.                    root,
  636.                    valuemask,
  637.                    values);
  638.   /*
  639.    * Inverse video selection.
  640.    */
  641.  
  642.   values->foreground = bkgnd_color.pixel;        
  643.   values->background = s_frg_color.pixel;
  644.   values->font = s_fnt_info->fid;
  645.   values->line_width = s_bdr_width;
  646.   inverse_select_GC = XCreateGC(display, 
  647.                 root,
  648.                 valuemask,
  649.                 values);
  650.   stipple_pixmap = XCreateBitmapFromData(display,
  651.                      root,
  652.                      stipple_bits,        
  653.                      stipple_width,        
  654.                      stipple_height);    
  655.     
  656.   /*
  657.    * Finally, inactive pane header and selections
  658.    */
  659.   valuemask |= (GCFillStyle | GCStipple);
  660.   values->foreground = s_frg_color.pixel;
  661.   values->background = bkgnd_color.pixel;
  662.   values->font = s_fnt_info->fid;
  663.   values->line_width = s_bdr_width;
  664.   values->fill_style = FillStippled;
  665.   values->stipple = stipple_pixmap;
  666.     
  667.   inact_GC = XCreateGC(display, 
  668.                root,
  669.                valuemask,
  670.                values);
  671.  
  672.   valuemask |= (GCGraphicsExposures);
  673.   values->graphics_exposures = False;
  674.   inact_GC_noexpose = XCreateGC (display, 
  675.                  root,
  676.                  valuemask, values);
  677.  
  678.  
  679.   /*
  680.    * Construct the XMenu object.
  681.    */
  682.   /* -------------------- Menu data -------------------- */
  683.   menu->menu_style = menu_style;
  684.   menu->menu_mode = menu_mode;
  685.   menu->freeze = freeze;
  686.   menu->aeq = 0;
  687.   menu->recompute = 1;
  688.   menu->parent = parent;
  689.   menu->height = 0;
  690.   menu->width = 0;
  691.   menu->mouse_cursor = mouse_cursor;
  692.   menu->assoc_tab = assoc_tab;
  693.   menu->p_list = pane;
  694.   /* -------------------- Pane window data -------------------- */
  695.   menu->p_style = p_style;
  696.   menu->p_events = DEF_P_EVENTS;
  697.   menu->p_fnt_info = p_fnt_info;
  698.   menu->p_fnt_pad = p_fnt_pad;
  699.   menu->p_spread = p_spread;
  700.   menu->p_bdr_width = p_bdr_width;
  701.   menu->flag_height = flag_height;
  702.   menu->p_width = 0;
  703.   menu->p_height = p_height;
  704.   menu->p_x_off = p_x_off;
  705.   menu->p_y_off = p_y_off;
  706.   menu->p_count = 0;
  707.   menu->pane_GC = pane_GC;
  708.   menu->x_pos = 0;
  709.   menu->y_pos = 0;
  710.   /* -------------------- Selection window data -------------------- */
  711.   menu->s_style = s_style;
  712.   menu->s_events = DEF_S_EVENTS;
  713.   menu->s_fnt_info = s_fnt_info;
  714.   menu->s_fnt_pad = s_fnt_pad;
  715.   menu->s_spread = s_spread;
  716.   menu->s_bdr_width = s_bdr_width; /* unnecessary */
  717.   menu->s_width = 0;
  718.   menu->s_height = s_height;
  719.   menu->s_x_off = s_x_off;
  720.   menu->s_y_off = s_y_off;
  721.   menu->s_count = 0;
  722.   menu->normal_select_GC = normal_select_GC;
  723.   menu->inverse_select_GC = inverse_select_GC;
  724.   menu->inact_GC = inact_GC;
  725.   /* -------------------- Color data -------------------- */
  726.   menu->p_bdr_color = p_bdr_color.pixel;
  727.   menu->s_bdr_color = s_bdr_color.pixel;
  728.   menu->p_frg_color = p_frg_color.pixel;
  729.   menu->s_frg_color = s_frg_color.pixel;
  730.   menu->bkgnd_color = bkgnd_color.pixel;
  731.   /* -------------------- Pixmap data -------------------- */
  732.   menu->p_bdr_pixmap = None;
  733.   menu->s_bdr_pixmap = None;
  734.   menu->p_frg_pixmap = None;
  735.   menu->s_frg_pixmap = None;
  736.   menu->bkgnd_pixmap = None;
  737.   menu->inact_pixmap = inact_bitmap;
  738.  
  739.   /*
  740.    * Return the completed XMenu.
  741.    */
  742.   _XMErrorCode = XME_NO_ERROR;
  743.   return(menu);
  744. }
  745.